package com.jketing.service.ams.work;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jketing.entity.ams.work.MaizeExperiment;
import com.jketing.entity.ams.work.Repetition;
import com.jketing.entity.ams.work.Variety;
import com.jketing.repository.ams.work.MaizeExperimentRepository;
import com.jketing.repository.ams.work.RepetitionRepository;
import com.jketing.repository.ams.work.VarietyRepository;
import com.jketing.service.BaseService;


/**
 * MaizeExperimentService	玉米试验服务类
 * 	功能：
 * 			继承扩展服务基类实现子类特有方法及功能；
 * 			如：多表查询和多表操作等；
 * 			可注入其它实体的仓库类或使用jdbc实现Dao调用本地Sql进行多表查询
 * 
 * @author  李荣华
 * @version v1.0
 * @date    2018-10-15
 * @since   Spring-data 1.11.4
 */
@Service
public class MaizeExperimentService extends BaseService<MaizeExperiment,String> {
	/**
	 * repository String按IOC容器管理的Bean类型自动注入模块仓库操作实例 .
	 */
	@Autowired
	private RepetitionRepository repetitionRepository;
	/**
	 * repository String按IOC容器管理的Bean类型自动注入模块仓库操作实例 .
	 */
	@Autowired
	private VarietyRepository varietyRepository;
	
	/**
	 * String按IOC容器管理的Bean类型自动注入模块仓库操作实例 .
	 * 	 用于初始化基类BaseRepository<T, ID>
	 *  惹是表达式查询同时初始化PredicateBuilder<T>
	 * @param BaseRepository<MaizeExperiment,String> repository
	 * 
	 * @return void
	 */
	@Autowired
	public void setBaseRepository(MaizeExperimentRepository repository) {
		super.setBaseRepository(repository);
	}
	
	public String getVarieties(String id) {
		ObjectMapper mapper = new ObjectMapper();
		String result = null;
		List<Variety> list = new ArrayList<Variety>();
		MaizeExperiment entity = getOne(id);
		for(Variety v:entity.getVarieties()) {
			for(Repetition r:v.getRepetitions()) {
				r.setVariety(null);
			}
			v.setProductionTest(null);
			list.add(v);
		}
		
		try {
			result = mapper.writeValueAsString(list);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public List<Variety> getVarietyList(String id) {
		List<Variety> list = new ArrayList<Variety>();
		MaizeExperiment entity = getOne(id);
		for(Variety v:entity.getVarieties()) {
			for(Repetition r:v.getRepetitions()) {
				r.getAxialColour();
			}
			list.add(v);
		}
		return list;
	}
	
	public List<Variety> getVarietyList(String id,String sortField) {
		List<Variety> list = new ArrayList<Variety>();
		MaizeExperiment entity = getOne(id);
		for(Variety v:entity.getVarieties()) {
			for(Repetition r:v.getRepetitions()) {
				r.getAxialColour();
			}
			list.add(v);
		}
		Collections.sort(list,new Comparator<Variety>() {

			@Override
			public int compare(Variety v1, Variety v2) {
				int result = 0;
				Class<Variety> classType = Variety.class;
				Field field = null;
				try {
					field = classType.getDeclaredField(sortField);
				} catch (NoSuchFieldException e) {
					e.printStackTrace();
				} catch (SecurityException e) {
					e.printStackTrace();
				}
				field.setAccessible(true); // 抑制Java对修饰符的检查
				try {
					float f1 = (Float)field.get(v1);
					float f2 = (Float)field.get(v2);
					result = (int)(f1 - f2);
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				return result;
			}
        });
		return list;
	}
	
	public MaizeExperiment save(MaizeExperiment entity,List<Variety> varieties) throws Exception{
		entity = save(entity);
		short count =0;
		Variety temp = null;
		Repetition repet = null;
		for(Variety v:varieties){
			temp = new Variety();
			temp.setId(getTimeId());
			temp.setProductionTest(entity);
			temp.setName(v.getName());
			temp = varietyRepository.save(temp);
			for(Repetition r:v.getRepetitions()){
				repet = new Repetition();
				BeanUtils.copyProperties(repet,r);
				repet.setSeedRate(0f);//计算折籽率
				repet.setSeedYield(0f);//计算出籽率
				repet.setPlotYield(0f);//计算小区产量
				repet.setYieldPerMu(0f);//计算亩产
				repet.setId(getTimeId());
				repet.setVariety(temp);
				repet = repetitionRepository.save(repet);
				temp.setSpikeLength(temp.getSpikeLength() + r.getSpikeLength());
				temp.setSpikeWide(temp.getSpikeWide() + r.getSpikeWide());
				temp.setSpikeRowNumber((short)(temp.getSpikeRowNumber() + r.getSpikeRowNumber()));
				temp.setRowGrainNumber((short)(temp.getRowGrainNumber() + r.getRowGrainNumber()));
				temp.setGrainColor(r.getGrainColor());
				temp.setGrainType(r.getGrainType());
				temp.setSpikeType(r.getSpikeType());
				temp.setAxialColour(r.getAxialColour());
				temp.setSpikeRot(temp.getSpikeRot() + r.getSpikeRot());
				temp.setGrainRot(temp.getGrainRot() + r.getGrainRot());
				temp.setAlopeciaAcuity(temp.getAlopeciaAcuity() + r.getAlopeciaAcuity());
				temp.setThousandGrainWeight(temp.getThousandGrainWeight() + r.getThousandGrainWeight());
				temp.setFreshPackageWeight(temp.getFreshPackageWeight() + r.getFreshPackageWeight());
				temp.setDryPackageWeight(temp.getDryPackageWeight() + r.getDryPackageWeight());
				temp.setDryGrainWeight(temp.getDryGrainWeight() + r.getDryGrainWeight());
				temp.setSeedRate(temp.getSeedRate() + repet.getSeedRate());
				temp.setSeedYield(temp.getSeedYield() + repet.getSeedYield());
				temp.setPlotFreshWeight(temp.getPlotFreshWeight() + r.getPlotFreshWeight());
				temp.setPlotYield(temp.getPlotYield() + repet.getPlotYield());
				temp.setYieldPerMu(temp.getYieldPerMu() + repet.getYieldPerMu());
				count++;
			}
			temp.setSpikeLength(temp.getSpikeLength()/count);//求平均
			temp.setSpikeLength((float)Math.round(temp.getSpikeLength()*100)/100);//保留两位小数
			temp.setSpikeWide(temp.getSpikeWide()/count);
			temp.setSpikeWide((float)Math.round(temp.getSpikeWide()*100)/100);//保留两位小数
			temp.setSpikeRowNumber((short)(temp.getSpikeRowNumber()/count));
			temp.setRowGrainNumber((short)(temp.getRowGrainNumber()/count));
			temp.setSpikeRot(temp.getSpikeRot()/count);
			temp.setSpikeRot((float)Math.round(temp.getSpikeRot()*100)/100);//保留两位小数
			temp.setGrainRot(temp.getGrainRot()/count);
			temp.setGrainRot((float)Math.round(temp.getGrainRot()*100)/100);//保留两位小数
			temp.setAlopeciaAcuity(temp.getAlopeciaAcuity()/count);
			temp.setAlopeciaAcuity((float)Math.round(temp.getAlopeciaAcuity()*100)/100);//保留两位小数
			temp.setThousandGrainWeight(temp.getThousandGrainWeight()/count);
			temp.setThousandGrainWeight((float)Math.round(temp.getThousandGrainWeight()*100)/100);//保留两位小数
			temp.setFreshPackageWeight(temp.getFreshPackageWeight()/count);
			temp.setFreshPackageWeight((float)Math.round(temp.getFreshPackageWeight()*100)/100);//保留两位小数
			temp.setDryPackageWeight(temp.getDryPackageWeight()/count);
			temp.setDryPackageWeight((float)Math.round(temp.getDryPackageWeight()*100)/100);//保留两位小数
			temp.setDryGrainWeight(temp.getDryGrainWeight()/count);
			temp.setDryGrainWeight((float)Math.round(temp.getDryGrainWeight()*100)/100);//保留两位小数
			temp.setSeedRate(temp.getSeedRate()/count);
			temp.setSeedRate((float)Math.round(temp.getSeedRate()*100)/100);//保留两位小数
			temp.setSeedYield(temp.getSeedYield()/count);
			temp.setSeedYield((float)Math.round(temp.getSeedYield()*100)/100);//保留两位小数
			temp.setPlotFreshWeight(temp.getPlotFreshWeight()/count);
			temp.setPlotFreshWeight((float)Math.round(temp.getPlotFreshWeight()*100)/100);//保留两位小数
			temp.setPlotYield(temp.getPlotYield()/count);
			temp.setPlotYield((float)Math.round(temp.getPlotYield()*100)/100);//保留两位小数
			temp.setYieldPerMu(temp.getYieldPerMu()/count);
			temp.setYieldPerMu((float)Math.round(temp.getYieldPerMu()*100)/100);//保留两位小数
		}
		return entity;
	}
	
	public MaizeExperiment update(MaizeExperiment entity,List<Variety> varieties) throws Exception{
		entity = this.saveAndFlush(entity);
		Iterator<Variety> it = entity.getVarieties().iterator();
		while (it.hasNext()) {
			varietyRepository.delete(it.next());
		}
		Variety temp = null;
		Repetition repet = null;
		for(Variety v:varieties){
			short count = 0;
			temp = new Variety();
			temp.setId(getTimeId());
			temp.setProductionTest(entity);
			temp.setName(v.getName());
			temp = varietyRepository.save(temp);
			for(Repetition r:v.getRepetitions()){
				repet = new Repetition();
				BeanUtils.copyProperties(repet,r);
				repet.setSeedRate(0f);//计算折籽率
				repet.setSeedYield(0f);//计算出籽率
				repet.setPlotYield(0f);//计算小区产量
				repet.setYieldPerMu(0f);//计算亩产
				repet.setId(getTimeId());
				repet.setVariety(temp);
				repet = repetitionRepository.save(repet);
				temp.setSpikeLength(temp.getSpikeLength() + r.getSpikeLength());
				temp.setSpikeWide(temp.getSpikeWide() + r.getSpikeWide());
				temp.setSpikeRowNumber((short)(temp.getSpikeRowNumber() + r.getSpikeRowNumber()));
				temp.setRowGrainNumber((short)(temp.getRowGrainNumber() + r.getRowGrainNumber()));
				if(StringUtils.isNotBlank(r.getGrainColor())) temp.setGrainColor(r.getGrainColor());				
				if(StringUtils.isNotBlank(r.getGrainType())) temp.setGrainType(r.getGrainType());
				if(StringUtils.isNotBlank(r.getSpikeType())) temp.setSpikeType(r.getSpikeType());
				if(StringUtils.isNotBlank(r.getAxialColour())) temp.setAxialColour(r.getAxialColour());
				temp.setSpikeRot(temp.getSpikeRot() + r.getSpikeRot());
				temp.setGrainRot(temp.getGrainRot() + r.getGrainRot());
				temp.setAlopeciaAcuity(temp.getAlopeciaAcuity() + r.getAlopeciaAcuity());
				temp.setThousandGrainWeight(temp.getThousandGrainWeight() + r.getThousandGrainWeight());
				temp.setFreshPackageWeight(temp.getFreshPackageWeight() + r.getFreshPackageWeight());
				temp.setDryPackageWeight(temp.getDryPackageWeight() + r.getDryPackageWeight());
				temp.setDryGrainWeight(temp.getDryGrainWeight() + r.getDryGrainWeight());
				temp.setSeedRate(temp.getSeedRate() + repet.getSeedRate());
				temp.setSeedYield(temp.getSeedYield() + repet.getSeedYield());
				temp.setPlotFreshWeight(temp.getPlotFreshWeight() + r.getPlotFreshWeight());
				temp.setPlotYield(temp.getPlotYield() + repet.getPlotYield());
				temp.setYieldPerMu(temp.getYieldPerMu() + repet.getYieldPerMu());
				count++;
			}
			temp.setSpikeLength(temp.getSpikeLength()/count);//求平均
			temp.setSpikeLength((float)Math.round(temp.getSpikeLength()*100)/100);//保留两位小数
			temp.setSpikeWide(temp.getSpikeWide()/count);
			temp.setSpikeWide((float)Math.round(temp.getSpikeWide()*100)/100);//保留两位小数
			temp.setSpikeRowNumber((short)(temp.getSpikeRowNumber()/count));
			temp.setRowGrainNumber((short)(temp.getRowGrainNumber()/count));
			temp.setSpikeRot(temp.getSpikeRot()/count);
			temp.setSpikeRot((float)Math.round(temp.getSpikeRot()*100)/100);//保留两位小数
			temp.setGrainRot(temp.getGrainRot()/count);
			temp.setGrainRot((float)Math.round(temp.getGrainRot()*100)/100);//保留两位小数
			temp.setAlopeciaAcuity(temp.getAlopeciaAcuity()/count);
			temp.setAlopeciaAcuity((float)Math.round(temp.getAlopeciaAcuity()*100)/100);//保留两位小数
			temp.setThousandGrainWeight(temp.getThousandGrainWeight()/count);
			temp.setThousandGrainWeight((float)Math.round(temp.getThousandGrainWeight()*100)/100);//保留两位小数
			temp.setFreshPackageWeight(temp.getFreshPackageWeight()/count);
			temp.setFreshPackageWeight((float)Math.round(temp.getFreshPackageWeight()*100)/100);//保留两位小数
			temp.setDryPackageWeight(temp.getDryPackageWeight()/count);
			temp.setDryPackageWeight((float)Math.round(temp.getDryPackageWeight()*100)/100);//保留两位小数
			temp.setDryGrainWeight(temp.getDryGrainWeight()/count);
			temp.setDryGrainWeight((float)Math.round(temp.getDryGrainWeight()*100)/100);//保留两位小数
			temp.setSeedRate(temp.getSeedRate()/count);
			temp.setSeedRate((float)Math.round(temp.getSeedRate()*100)/100);//保留两位小数
			temp.setSeedYield(temp.getSeedYield()/count);
			temp.setSeedYield((float)Math.round(temp.getSeedYield()*100)/100);//保留两位小数
			temp.setPlotFreshWeight(temp.getPlotFreshWeight()/count);
			temp.setPlotFreshWeight((float)Math.round(temp.getPlotFreshWeight()*100)/100);//保留两位小数
			temp.setPlotYield(temp.getPlotYield()/count);
			temp.setPlotYield((float)Math.round(temp.getPlotYield()*100)/100);//保留两位小数
			temp.setYieldPerMu(temp.getYieldPerMu()/count);
			temp.setYieldPerMu((float)Math.round(temp.getYieldPerMu()*100)/100);//保留两位小数
		}
		return entity;
	}
}
